import 'dart:io';
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:mobile_app.core/core/domain/entities/dialect.dart';
import 'package:mobile_app.core/core/domain/entities/learning_content/lexical_item/lexical_item.dart';
import 'package:mobile_app.core/core/presentation/helpers/screen_util_mixin.dart';
import 'package:mobile_app.core/core/presentation/widget_config.dart';
import 'package:mobile_app.core/core/presentation/widgets/card_content_horizontal_padding.dart';
import 'package:mobile_app.core/core/presentation/widgets/card_more_action_button.dart';
import 'package:mobile_app.home.core/core/presentation/helpers/auto_scalable_text_mixin.dart';
import 'package:mobile_app.home.core/core/presentation/helpers/card_view_mixin.dart';
import 'package:mobile_app.home.core/core/presentation/theme/home_core_theme.dart';
import 'package:mobile_app.home.core/core/presentation/widgets/pronunciation_button.dart';
import 'package:mobile_app.home.core/core/presentation/widgets/scalable_lexical_item_text.dart';
import 'package:mobile_app.home.core/core/presentation/widgets/use_case_view.dart';

class CardFullContent extends StatefulWidget {
  const CardFullContent({
    required this.lexicalItem,
    required this.dialect,
    required this.safeToPronounce,
    required this.onLexicalItemPronunciationButtonPressed,
    required this.onPronunciationCautionButtonPressed,
    required this.onUseCasePronunciationButtonPressed,
    this.imagePath,
    this.onMoreActionButtonPressed,
    super.key,
  });

  final LexicalItem lexicalItem;
  final Dialect dialect;
  final bool safeToPronounce;
  final String? imagePath;
  final VoidCallback onLexicalItemPronunciationButtonPressed;
  final VoidCallback onPronunciationCautionButtonPressed;
  final VoidCallback? onMoreActionButtonPressed;
  final void Function(LexicalItemUseCase) onUseCasePronunciationButtonPressed;

  @override
  State<CardFullContent> createState() => _CardFullContentState();
}

class _CardFullContentState extends State<CardFullContent>
    with CardViewMixin, AutoScalableTextMixin, ScreenUtilMixin {
  double get _scaleFactor => logWidthScaleFactor;

  late bool _imageAvailable;

  Widget _buildCardContent({
    required BuildContext context,
  }) {
    if (_imageAvailable) {
      return _buildImageCardContent(
        context: context,
      );
    }

    return _buildImagelessCardContent(
      context: context,
    );
  }

  Widget _buildImageCardContent({
    required BuildContext context,
  }) {
    final pronunciationButtonSize = kImageCardPronunciationButtonSize * _scaleFactor;
    final pronunciationButtonBorderWidth = kImageCardPronunciationButtonBorderSize * _scaleFactor;

    return Column(
      children: [
        Stack(
          children: [
            Padding(
              padding: EdgeInsets.only(
                bottom: pronunciationButtonSize / 2 + pronunciationButtonBorderWidth,
              ),
              child: SizedBox(
                width: double.infinity,
                child: Image.file(
                  File(widget.imagePath!),
                  fit: BoxFit.cover,
                  filterQuality: FilterQuality.medium,
                ),
              ),
            ),
            Positioned.fill(
              child: Align(
                alignment: Alignment.bottomCenter,
                child: PronunciationButton(
                  size: pronunciationButtonSize,
                  borderWidth: pronunciationButtonBorderWidth,
                  borderColor: HomeCoreTheme.of(context).cardColor,
                  onPressed: widget.onLexicalItemPronunciationButtonPressed,
                ),
              ),
            ),
          ],
        ),
        Expanded(
          child: CardContentHorizontalPadding(
            child: LayoutBuilder(
              builder: (context, constraints) {
                final lexicalItem = widget.lexicalItem;

                final localizedLexicalItemUnit = getLocalizedLexicalItemUnit(
                  lexicalItem: lexicalItem,
                  context: context,
                );

                final lexicalItemNameConstraints = BoxConstraints(
                  maxWidth: constraints.maxWidth,
                  maxHeight: constraints.maxHeight * 0.35,
                );

                final preferredLexicalItemNameTextStyle =
                    HomeCoreTheme.of(context).textTheme.cardLexicalItemName;

                final lexicalItemNameTextHeight = getTextHeight(
                  text: lexicalItem.title + lexicalItem.translation,
                  style: preferredLexicalItemNameTextStyle,
                  textScaleFactor: _scaleFactor,
                );

                final maxLines = getLexicalItemNameMaxLines(
                  textHeight: lexicalItemNameTextHeight,
                  maxHeight: lexicalItemNameConstraints.maxHeight,
                );

                final lexicalItemNameMinFontSize =
                    preferredLexicalItemNameTextStyle.fontSize! / kMaxLexicalItemNameShrinkFactor;

                final titleFontSize = calculateFontSize(
                  text: lexicalItem.title,
                  constraints: lexicalItemNameConstraints,
                  style: preferredLexicalItemNameTextStyle,
                  minFontSize: lexicalItemNameMinFontSize,
                  textScaleFactor: _scaleFactor,
                  maxLines: maxLines,
                );

                final translationFontSize = calculateFontSize(
                  text: lexicalItem.translation,
                  constraints: lexicalItemNameConstraints,
                  style: preferredLexicalItemNameTextStyle,
                  minFontSize: lexicalItemNameMinFontSize,
                  textScaleFactor: _scaleFactor,
                  maxLines: maxLines,
                );

                final scaledLexicalItemNameFontSize = min(titleFontSize, translationFontSize);
                final scaledLexicalItemNameTextStyle = preferredLexicalItemNameTextStyle.copyWith(
                  fontSize: scaledLexicalItemNameFontSize,
                );

                final lexicalItemTranscription = getLexicalItemTranscription(
                  lexicalItem: lexicalItem,
                  dialect: widget.dialect,
                );

                final lexicalItemUnitTopPadding = scaledLexicalItemNameTextStyle.height! *
                    scaledLexicalItemNameFontSize *
                    kLexicalItemUnitTopPaddingRatio;

                return Column(
                  children: [
                    const Spacer(flex: 2),
                    ScalableLexicalItemText(
                      text: lexicalItem.title,
                      style: scaledLexicalItemNameTextStyle,
                      maxLines: maxLines,
                    ),
                    if (lexicalItemTranscription != null)
                      buildTranscriptionRow(
                        lexicalItemTranscription: lexicalItemTranscription,
                        scaledLexicalItemNameFontSize: scaledLexicalItemNameFontSize,
                        safeToPronounce: widget.safeToPronounce,
                        onPronunciationCautionButtonPressed:
                            widget.onPronunciationCautionButtonPressed,
                        context: context,
                      ),
                    const Spacer(flex: 2),
                    ScalableLexicalItemText(
                      text: lexicalItem.translation,
                      style: scaledLexicalItemNameTextStyle,
                      maxLines: maxLines,
                    ),
                    if (lexicalItem is InbuiltLexicalItem)
                      Padding(
                        padding: EdgeInsets.only(
                          top: lexicalItemUnitTopPadding,
                        ),
                        child: Text(
                          localizedLexicalItemUnit,
                          style: HomeCoreTheme.of(context).textTheme.cardLexicalItemUnit,
                          textAlign: TextAlign.center,
                          textScaleFactor: _scaleFactor,
                        ),
                      ),
                    const Spacer(flex: 3),
                  ],
                );
              },
            ),
          ),
        ),
      ],
    );
  }

  Widget _buildImagelessCardContent({
    required BuildContext context,
  }) {
    return CardContentHorizontalPadding(
      child: LayoutBuilder(
        builder: (context, constraints) {
          final lexicalItem = widget.lexicalItem;

          var lexicalItemUnitTextHeight = 0.0;

          final localizedLexicalItemUnit = getLocalizedLexicalItemUnit(
            lexicalItem: lexicalItem,
            context: context,
          );

          if (lexicalItem is InbuiltLexicalItem) {
            lexicalItemUnitTextHeight = getTextHeight(
              text: localizedLexicalItemUnit,
              style: HomeCoreTheme.of(context).textTheme.cardLexicalItemUnit,
              textScaleFactor: _scaleFactor,
            );
          }

          final pronunciationButtonSize = kImagelessCardPronunciationButtonSize * _scaleFactor;

          final lexicalItemNameConstraints = BoxConstraints(
            maxWidth: constraints.maxWidth,
            maxHeight:
                (constraints.maxHeight - lexicalItemUnitTextHeight - pronunciationButtonSize) *
                    0.35,
          );

          final preferredLexicalItemNameTextStyle =
              HomeCoreTheme.of(context).textTheme.cardLexicalItemName;

          final lexicalItemNameTextHeight = getTextHeight(
            text: lexicalItem.title + lexicalItem.translation,
            style: preferredLexicalItemNameTextStyle,
            textScaleFactor: _scaleFactor,
          );

          final maxLines = getLexicalItemNameMaxLines(
            textHeight: lexicalItemNameTextHeight,
            maxHeight: lexicalItemNameConstraints.maxHeight,
          );

          final lexicalItemNameMinFontSize =
              preferredLexicalItemNameTextStyle.fontSize! / kMaxLexicalItemNameShrinkFactor;

          final titleFontSize = calculateFontSize(
            text: lexicalItem.title,
            constraints: lexicalItemNameConstraints,
            style: preferredLexicalItemNameTextStyle,
            minFontSize: lexicalItemNameMinFontSize,
            textScaleFactor: _scaleFactor,
            maxLines: maxLines,
          );

          final translationFontSize = calculateFontSize(
            text: lexicalItem.translation,
            constraints: lexicalItemNameConstraints,
            style: preferredLexicalItemNameTextStyle,
            minFontSize: lexicalItemNameMinFontSize,
            textScaleFactor: _scaleFactor,
            maxLines: maxLines,
          );

          final scaledLexicalItemNameFontSize = min(titleFontSize, translationFontSize);
          final scaledLexicalItemNameTextStyle = preferredLexicalItemNameTextStyle.copyWith(
            fontSize: scaledLexicalItemNameFontSize,
          );

          final lexicalItemTranscription = getLexicalItemTranscription(
            lexicalItem: lexicalItem,
            dialect: widget.dialect,
          );

          final lexicalItemUnitTopPadding = scaledLexicalItemNameTextStyle.height! *
              scaledLexicalItemNameFontSize *
              kLexicalItemUnitTopPaddingRatio;

          return Column(
            children: [
              const Spacer(),
              ScalableLexicalItemText(
                text: lexicalItem.title,
                style: scaledLexicalItemNameTextStyle,
                maxLines: maxLines,
              ),
              if (lexicalItemTranscription != null)
                buildTranscriptionRow(
                  lexicalItemTranscription: lexicalItemTranscription,
                  scaledLexicalItemNameFontSize: scaledLexicalItemNameFontSize,
                  safeToPronounce: widget.safeToPronounce,
                  onPronunciationCautionButtonPressed: widget.onPronunciationCautionButtonPressed,
                  context: context,
                ),
              const Spacer(),
              PronunciationButton(
                size: pronunciationButtonSize,
                onPressed: widget.onLexicalItemPronunciationButtonPressed,
              ),
              const Spacer(),
              ScalableLexicalItemText(
                text: lexicalItem.translation,
                style: scaledLexicalItemNameTextStyle,
                maxLines: maxLines,
              ),
              if (lexicalItem is InbuiltLexicalItem)
                Padding(
                  padding: EdgeInsets.only(
                    top: lexicalItemUnitTopPadding,
                  ),
                  child: Text(
                    localizedLexicalItemUnit,
                    style: HomeCoreTheme.of(context).textTheme.cardLexicalItemUnit,
                    textAlign: TextAlign.center,
                    textScaleFactor: _scaleFactor,
                  ),
                ),
              const Spacer(),
            ],
          );
        },
      ),
    );
  }

  @override
  void initState() {
    super.initState();

    _imageAvailable = widget.imagePath != null;
  }

  @override
  void didUpdateWidget(CardFullContent oldWidget) {
    super.didUpdateWidget(oldWidget);

    if (oldWidget.imagePath == null && widget.imagePath != null) {
      final imageFile = File(widget.imagePath!);
      final image = FileImage(imageFile);

      precacheImage(image, context).then((_) {
        if (mounted) {
          setState(() {
            _imageAvailable = true;
          });
        }
      });
    } else if (oldWidget.imagePath != null && widget.imagePath == null) {
      _imageAvailable = false;
    }
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        return SingleChildScrollView(
          physics: const ClampingScrollPhysics(),
          child: Column(
            children: [
              SizedBox(
                width: constraints.maxWidth,
                height: constraints.maxHeight,
                child: Stack(
                  fit: StackFit.expand,
                  children: [
                    _buildCardContent(
                      context: context,
                    ),
                    if (widget.onMoreActionButtonPressed != null)
                      Positioned(
                        top: 0,
                        right: 0,
                        child: CardMoreActionButton(
                          onPressed: widget.onMoreActionButtonPressed!,
                        ),
                      ),
                  ],
                ),
              ),
              if (widget.lexicalItem.useCases.isNotEmpty)
                UseCaseView(
                  useCases: widget.lexicalItem.useCases,
                  pronounceable: true,
                  showExample: true,
                  showTranslation: true,
                  showDivider: false,
                  onUseCasePronunciationButtonPressed: widget.onUseCasePronunciationButtonPressed,
                ),
            ],
          ),
        );
      },
    );
  }
}
